home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / SDKs / PCI Driver Development Kit / • Samples / Driver Samples / SCSI samples / SCSI 950629 / NCR_DriverProject / Src / DMATransfer.h < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-20  |  8.4 KB  |  199 lines  |  [TEXT/MPCC]

  1. /*                                    DMATransfer.h                                    */
  2. /*
  3.  * DMATransfer.h
  4.  * Copyright © 1995 Apple Computer Inc. All rights reserved.
  5.  */
  6. /*    .___________________________________________________________________________________.
  7.       | This library simplifies using PrepareMemoryForIO with DMA and non-DMA hardware    |
  8.     | devices. These functions can be called from any interrupt level.                    |
  9.     |                                                                                    |
  10.     | PrepareDMATransfer prepares the next segment (logical or physical) that can        |
  11.     | be computed from the current state of the I/O table. The caller must adapt the    |
  12.     | result if required maximum transfer length limitations.                            |
  13.     |                                                                                    |
  14.     | Usage:                                                                            |
  15.     |        while ((myIOTable.state & kIOStateDone) == 0) {                                |
  16.     |            status = PrepareMemoryForIO(&myIOTable);    // Do preparation            |
  17.     |            if (status == noErr) {                        // Start dma preparation    |
  18.     |                status = InitializeDMATransfer(                                        |
  19.     |                            &myIOTable,                                                |
  20.     |                            myLogicalAlignment,                                        |
  21.     |                            &myDMATable                                                |
  22.     |                        );                                                            |
  23.     |                while (status == noErr) {                // Start dma operation        |
  24.     |                    status = PrepareDMATransfer(                                    |
  25.     |                                &myDMATable,                                        |
  26.     |                                &myNextTransfer,                                    |
  27.     |                                &nextIsLogical                                        |
  28.     |                            );                                                        |
  29.     |                    if (status == noErr) {                                            |
  30.     |                        if (nextIsLogical)                                            |
  31.     |                            DoLogicalTransfer(&myNextTransfer);                        |
  32.     |                        else {                                                        |
  33.     |                            DoPhysicalTransfer(&myNextTransfer);                    |
  34.     |                        }                                                            |
  35.     |                    } // For all DMA segments for this preparation.                    |
  36.     |                } // while there is data to transmit                                |
  37.     |                CheckpointIO(myIOTable.preparationID, kNilOptions);                    |
  38.     |        } // if PrepareMemoryForIO succeeded                                        |
  39.     .___________________________________________________________________________________.
  40.  */
  41.  
  42. #ifndef DMATransfer
  43. #define DMATransfer
  44.  
  45. #include <Types.h>
  46. #include <Kernel.h>
  47. #include <Errors.h>
  48.  
  49. struct DMATransferInfo {
  50.         const IOPreparationTable *ioTablePtr;            /* Caller's I/O Prep Table    */
  51.         UInt32                    logicalAlignment;        /* Caller's parameter        */
  52.         ItemCount                scatterGatherIndex;        /* 0 to range.entryCount    */
  53.         ByteCount                prepareCount;            /* 0 to lengthPrepared        */
  54.         ByteCount                rangeCount;                /* 0 to range length        */
  55.         ByteCount                rangeLength;            /* Length of this sg area    */
  56.         ItemCount                physicalMapIndex;        /* 0 to mappingEntryCount    */
  57.         ByteCount                physicalStart;            /* 0 to physicalLength        */
  58.         ByteCount                physicalEnd;            /* DMA high-water mark        */
  59.          ByteCount                firstPageOffset;        /* Logical transfer hack    */
  60.         AddressRange            physicalRange;            /* Current physical segment    */
  61.         AddressRange            logicalStart;            /* Initial logical segment    */
  62.         AddressRange            logicalEnd;                /* Final logical segment    */
  63. };
  64. typedef struct DMATransferInfo DMATransferInfo, *DMATransferInfoPtr;
  65.  
  66. /*    .___________________________________________________________________________________.
  67.       | InitializeDMATransfer                                                                |
  68.     |                                                                                    |
  69.     | Initialize the DMATransferInfo record.                                            |
  70.     | Input:                                                                            |
  71.     |    ioTable                The prepared I/O Preparation table. It is "ready to run"    |
  72.     |    logicalGranularity    This is a power of two that is used to group the transfer    |
  73.     |                        into logical and physical segments. If zero, only physical    |
  74.     |                        transfers will be reported. If one and a logical segment    |
  75.     |                        begins on an odd-byte boundary, PrepareDMATransfer will        |
  76.     |                        return a one-byte logical transfer, then one or more        |
  77.     |                        physical transfers then, if necessary, a one-byte logical    |
  78.     |                        transfer.                                                    |
  79.     |                                                                                    |
  80.     | Output:                                                                            |
  81.     |    dmaTablePtr            The DMATransferInfo record that will manage this transfer.    |
  82.     |                                                                                    |
  83.     | Result:                                                                            |
  84.     |    noErr                Normal.                                                        |
  85.     |    paramErr            Bad parameters (ioTable or dmaTablePtr are NULL or an error    |
  86.     |                        in the IOTable parameters.                                    |
  87.     |                                                                                    |
  88.     | Set the IOTable parameter block as follows:                                        |
  89.     |        kIOLogicalRanges            Required if non-zero logical granularity.        |
  90.     |        kIOMinimalLogicalMapping    Required if non-zero logical granularity.        |
  91.     |    mappingEntryCount    > 0                                                            |
  92.     |    options:                                                                        |
  93.     |        kIOTransferIsLogical        Must be FALSE                                    |
  94.     |        kIOMinimalLogicalMapping    Required                                        |
  95.     |        kIOIsInput or kIOIsOutput    One is required                                    |
  96.     .___________________________________________________________________________________.
  97.  */
  98. OSStatus                    InitializeDMATransfer(
  99.         const IOPreparationTable *ioTablePtr,
  100.         UInt32                    logicalGranularity,
  101.         DMATransferInfoPtr        dmaTablePtr
  102.     );
  103.  
  104. /*    .___________________________________________________________________________________.
  105.       | PrepareDMATransfer                                                                |
  106.     |                                                                                    |
  107.     | Prepare the next DMA segment.                                                        |
  108.     | Input:                                                                            |
  109.     |    dmaTablePtr            The DMATransferInfo record that will manage this transfer.    |
  110.     |                                                                                    |
  111.     | Output:                                                                            |
  112.     |    nextTransferRange    Gets the segment start address and transfer length.            |
  113.     |    nextIsLogical        TRUE if this is a logical address.                            |
  114.     |                                                                                    |
  115.     | Result:                                                                            |
  116.     |    noErr                Normal                                                         |
  117.     |    paramErr            Programming bug.                                            |
  118.     |    eofErr                Nothing more to transfer.                                    |
  119.     |                                                                                    |
  120.     | Notes:                                                                            |
  121.     |                                                                                    |
  122.     |    eofErr is a normal status results. They should be replaced by                    |
  123.     |    by private error codes.                                                            |
  124.     |                                                                                    |
  125.     |    If logical addresses are needed, the PrepareMemoryForIO must provide a "minimal    |
  126.     |    logical mapping" table.                                                            |
  127.     .___________________________________________________________________________________.
  128.  */
  129. OSStatus                    PrepareDMATransfer(
  130.         DMATransferInfoPtr        dmaTablePtr,
  131.         AddressRange            *nextTransferRange,
  132.         Boolean                    *nextIsLogical
  133.     );
  134.  
  135. /*
  136.  * These macros are useful for DMA preparation.
  137.  */
  138. /*    .___________________________________________________________________________________.
  139.       | NextPageIsContiguous                                                                |
  140.     |                                                                                    |
  141.     | TRUE if the page following this one is physically contiguous with this page.        |
  142.     |                                                                                    |
  143.     | Input:                                                                            |
  144.     |    map                    The physical map table.                                        |
  145.     |    i                    The current location in the table.                            |
  146.     |                                                                                    |
  147.     | Result:                                                                            |
  148.     |    TRUE if the pages are contiguous.                                                |
  149.     .___________________________________________________________________________________.
  150.  */
  151. #define NextPageIsContiguous(map, i) (NextPageBaseAddress((map)[i]) == (map)[(i) + 1])
  152.  
  153. /*    .___________________________________________________________________________________.
  154.       | NextPageBaseAddress                                                                |
  155.     |                                                                                    |
  156.     | Compute the base of the page that follows this page. This is needed to determine    |
  157.     | whether a logical address range is stored in a contiguous physical address range.    |
  158.     |                                                                                    |
  159.     | Input:                                                                            |
  160.     |    theAddress            The start of the physical area.                                |
  161.     |                                                                                    |
  162.     | Result:                                                                            |
  163.     |    The start of the next physical page.                                            |
  164.     .___________________________________________________________________________________.
  165.  */
  166. #define NextPageBaseAddress(theAddress) \
  167.     ((PhysicalAddress) PageBaseAddress((UInt32) (theAddress) + gPageSize))
  168.  
  169. /*    .___________________________________________________________________________________.
  170.       | PageBaseAddress                                                                    |
  171.     |                                                                                    |
  172.     | Return the base of the page that contains the argument.                            |
  173.     |                                                                                    |
  174.     | Input:                                                                            |
  175.     |    theAddress            The start of the physical area.                                |
  176.     |                                                                                    |
  177.     | Result:                                                                            |
  178.     |    The start of physical page that contains this address.                            |
  179.     .___________________________________________________________________________________.
  180.  */
  181. #define PageBaseAddress(theAddress) ((theAddress) & ~gPageMask)
  182.  
  183. /*    .___________________________________________________________________________________.
  184.       | PageOffset                                                                        |
  185.     |                                                                                    |
  186.     | Return the position of this address within its page.    .                            |
  187.     |                                                                                    |
  188.     | Input:                                                                            |
  189.     |    theAddress            The start of the logical or physical area.                    |
  190.     |                                                                                    |
  191.     | Result:                                                                            |
  192.     |    The offset of the area within the physical page.                                |
  193.     .___________________________________________________________________________________.
  194.  */
  195. #define PageOffset(theAddress) ((theAddress) & gPageMask)
  196.  
  197. #endif /* __DMATransfer__ */
  198.  
  199.